package com.hengshan.service.impl;

import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hengshan.common.utils.ServletUtils;
import com.hengshan.domain.entity.SysLoginLog;
import com.hengshan.domain.event.LoginEvent;
import com.hengshan.domain.vo.PageVo;
import com.hengshan.mapper.SysLoginLogMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 系统访问记录(SysLoginLog)表服务实现类
 *
 * @author muxijun
 * @since 2024-01-22 18:12:28
 */
@Service("sysLoginLogService")
@Slf4j
public class SysLoginLogServiceImpl extends ServiceImpl<SysLoginLogMapper, SysLoginLog> {

    /**
     * 批量删除系统登录日志
     *
     * @param ids 需要删除的登录日志ID
     * @return 结果
     */
    public boolean deleteByIds(List<Long> ids) {
        return removeBatchByIds(ids);
    }

    /**
     * 查询系统登录日志集合
     *
     * @param sysLoginLog 登录日志对象
     * @return 登录记录集合
     */
    public List<SysLoginLog> getList(SysLoginLog sysLoginLog) {
        Map<String, Object> params = sysLoginLog.getParams();
        LambdaQueryWrapper<SysLoginLog> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.hasText(sysLoginLog.getIp()), SysLoginLog::getIp, sysLoginLog.getIp())
                .like(StringUtils.hasText(sysLoginLog.getUsername()), SysLoginLog::getUsername, sysLoginLog.getUsername())
                .between(params.get("beginTime") != null && params.get("endTime") != null,
                        SysLoginLog::getCreateTime, params.get("beginTime"), params.get("endTime"))
                .orderByDesc(SysLoginLog::getId);
        return list(wrapper);
    }

    /**
     * 分页查询系统登录日志
     *
     * @param pageNum     第几页
     * @param pageSize    每页条数
     * @param sysLoginLog 登录日志对象
     * @return 登录记录集合
     */
    public PageVo<SysLoginLog> getPageList(int pageNum, int pageSize, SysLoginLog sysLoginLog) {
        Map<String, Object> params = sysLoginLog.getParams();
        LambdaQueryWrapper<SysLoginLog> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.hasText(sysLoginLog.getIp()), SysLoginLog::getIp, sysLoginLog.getIp())
                .like(StringUtils.hasText(sysLoginLog.getUsername()), SysLoginLog::getUsername, sysLoginLog.getUsername())
                .between(params.get("beginTime") != null && params.get("endTime") != null,
                        SysLoginLog::getCreateTime, params.get("beginTime"), params.get("endTime"));
        Page<SysLoginLog> page = new Page<>(pageNum, pageSize);
        page(page, wrapper);
        return new PageVo<>(page.getRecords(), page.getTotal());
    }

    /**
     * 清空系统登录日志
     */
    public void cleanLoginLog() {
        remove(new LambdaQueryWrapper<>());
    }

    /**
     * 监听登录事件,记录登录信息
     *
     * @param loginEvent 登录事件
     */
    @Async
    @EventListener
    public void recordLoginLog(LoginEvent loginEvent) {
        HttpServletRequest request = loginEvent.getRequest();
        final UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
        final String ip = ServletUtils.getClientIP(request);
        String address = "XX XX";
        String s = ip + address + loginEvent.getUsername() + loginEvent.getStatus() + loginEvent.getMessage();
        // 打印信息到日志
        log.info(s, loginEvent.getArgs());
        // 获取客户端操作系统
        String os = userAgent.getOs().getName();
        // 获取客户端浏览器
        String browser = userAgent.getBrowser().getName();
        // 封装对象
        SysLoginLog loginLog = new SysLoginLog();
        loginLog.setUsername(loginEvent.getUsername());
        loginLog.setIp(ip);
        loginLog.setLocation(address);
        loginLog.setBrowser(browser);
        loginLog.setOs(os);
        loginLog.setMessage(loginEvent.getMessage());
        loginLog.setCreateTime(new Date());
        loginLog.setStatus(loginEvent.getStatus());
        // 插入数据
        save(loginLog);
    }
}

